################################################################################
# контроллер каталога
################################################################################
@CLASS
AdminController
@USE
application.p
@BASE
ApplicationController
@OPTIONS
locals
@factoryCreate[h]
$result[^AdminController::new[$h]]
@auto[]
$Factory:hClasses.[$self.CLASS_NAME][$self.CLASS]
################################################################################


# конструктор
@init[]
	^BASE:init[]


# действие для адреса /collections/
@ACTION_index[]
<p>что-то выводим в индекс</p>


@ACTION_edit[]
<![CDATA[
^if(def $form:submit){
	
	$hFieldsToEdit[^getFieldsToEdit[$form:fields]]

	^rem{ разобраться, что тут поменялось, и сделать ALTER table CHANGE }
#	^hFieldsToEdit.foreach[sName;hParam]{
#		^if($sName ne $hParam.name || ^rem{ конверт_SQL_тип ne $hParam.type } ){
#			обновить тип и имя.
#			^dstop[$sName ne $hParam.name]
#		}
#	}
###	^dstop[$hFieldsToEdit]
	
	$hFieldsToAdd[^getFieldsToAdd[$form:fields]]
	^use[Migration.p]
	$oMG[^Migration::new[]]	
	$oMG.up[
		$.alter_table[$form:tableName]

		^rem{ если нужно удалить какие-то поля - сейчас самое время }
		^if($form:tables.dropField is table){
			$tDropFields[$form:tables.dropField]
			$.drop_column[^tDropFields.menu{$tDropFields.field}[,]]
		}

		^rem{ добавить поля }
		$.add_column[
			^rem{ последовательный перебор добавляемых полей (сортировка по ключу) }
			^Migration:foreach[$hFieldsToAdd;key;value]{
				
				^switch[$value.type]{
					^rem{ строка }
					^case[string]{
						$.[$value.name][
							$.type[varchar(255)]
							$.not_null[true]
							$.default[]
						]
					}
					^rem{ текст }
					^case[text]{
						$.[$value.name][
							$.type[text]
							$.not_null[true]
							$.default[]
						]
					}
					^rem{ целое }
					^case[integer]{
						$.[$value.name][
							$.type[integer(11)]
							$.not_null[false]
						]
					}
					^rem{ фотки (зависимый класс) }
					^case[photos]{
						^addClass[$form:className;$value.name;
							$.sClassName[Picture]
						]
					}
					^case[DEFAULT]{^throw[unknown_field_type;;Много типов разных понимаю, но тип поля «${value.type}» не знаю я.]}
				}
				
				
			}
		]
	]
	^oMG.migrate[]
	^ActiveRecord:getFields[$form:className]
}

^showForm[]

]]>


@addClass[sClassName;sLinkName;hParams]
$sFileName[/../data/app/models/^sClassName.lower[].p]
$f[^file::load[binary;$sFileName]]
$sText[$f.text]

$hHasMany[$ActiveRecord:hO.[$sClassName].hHasMany]
^if(^hHasMany.contains[$sLinkName]){
	^throw[link_exists;;Уже есть связь с именем "$sLinkName"]
}

# добавить связь
# тут фактически меняется хеш параметров класса,
# так что новая зависимость уже добавлена с этого момента, без перезагрузки класса
$hHasMany.[$sLinkName][$hParams]

# вытаскиваю объявление hHasMany из текста описания класса и заменяю на обновленный хеш
$sText[^sText.match[\^$hI\.hHasMany\[((\[([^^\[\]]|\[[^^\[\]]*])*\])|[^^\[\]]*)*\]][i]{^$hI.hHasMany^[^hashToString[$hHasMany]^]}]

^sText.save[$sFileName]


# выводит хеш в виде строки с нужным количеством табуляций
@hashToString[var;l]
$l(^l.int(0))
^if($var is hash){$result[
^var.foreach[key;value]{^for[i](0;$l){	}^$.$key^[^hashToString[$value]($l+1)^]
}^for[i](1;$l){	}]
}{$result[$var]}


@getFieldsToEdit[hFields]
$result[^hash::create[]]
^hFields.foreach[sFieldName;sFieldValue]{
	^if(^sFieldName.match[^^fieldName_[\S]+^$]){
		$sKey[^sFieldName.mid(10)]
		$hT[
			$.name[$sFieldValue]
			$.type[$form:[fieldType_$sKey]]
		]
		^if(def $hT.name && def $hT.type){
			$result.$sKey[$hT]
		}
	}
}


@getFieldsToAdd[hFields]
$result[^hash::create[]]
^hFields.foreach[sFieldName;sFieldValue]{
	^if(^sFieldName.match[^^addField_[\d]{3}^$]){
		$sKey[^sFieldName.right(3)]
		$hT[
			$.name[$sFieldValue]
			$.type[$form:[fieldType_$sKey]]
		]
		^if(def $hT.name && def $hT.type){
			$result.$sKey[$hT]
		}
	}
}


@showForm[]

# 	$hPathParam[^h0.sPath.split[/;h]]
# 	$sClassName[^hPathParam.0.match[^^(\w)(.*)][]{^match.1.upper[]^match.2.lower[]}]
# 	$iId[^hPathParam.1.int(0)]

<form method="POST">
	<input type="hidden" name="className" value="$ActiveRecord:hO.[Calendar].sClassName" id="className">
	<input type="hidden" name="tableName" value="$ActiveRecord:hO.[Calendar].sTableName" id="tableName">

	<p><a href="/collections/list">Список</a></p>
	
	<h1>Метапрограммирование</h1>
	
	<p>Классы, унаследованные от Exhibit (коллекции, короче говоря):</p>
	<ul>
		^ActiveRecord:hO.foreach[key;val]{
			^if($val.sBaseClassName eq Exhibit && $val.sClassName ne Exhibit){
				<li>$key</li>
			}
		}
	</ul>
	
	<h2>Класс Calendar</h2>
	
	<h4>Подчиненные классы</h4>
	$hHasMany[$ActiveRecord:hO.[Calendar].hHasMany]
	^if($hHasMany){<p>^hHasMany.foreach[k;v]{$k}[, ]</p>}{<p>Нет подчиненных классов</p>}
	
	<h4>Поля класса</h4>
	^if(def $ActiveRecord:hO.[Calendar]){
		<ul>
			^rem{ данные берутся из таблицы, чтобы учесть порядок }
			$tFields[$ActiveRecord:hO.[Calendar].tFields]
			^tFields.menu{
				<li>
					<input type="checkbox" name="dropField" ^if($tFields.Field eq id){disabled=""} value="$tFields.Field">
					Имя: <input type="text" name="fieldName_${tFields.Field}" ^if($tFields.Field eq id){disabled=""} value="$tFields.Field">
					Тип: ^printClassType[$tFields.Field;$tFields.Type]($tFields.Field eq id)
				</li>
			}
		</ul>
	}

	<h4>Добавить свойства</h4>
	Имя: <input type="text" name="addField_001" value="">
	Тип: ^printClassType[001]
	
	<p><input type="submit" name="submit" value="Заебись!" id="some_name"></p>

</form>


@printClassType[sFieldName;sSqlType;bDisable]
<select name="fieldType_$sFieldName" ^if($bDisable){disabled=""}>
	<option value="">--</option>
	<option ^if($sSqlType eq "varchar(255)"){selected=""} value="string">строка</option>
	<option ^if($sSqlType eq text){selected=""} value="text">текст</option>
	<option ^if(^sSqlType.left(3) eq int){selected=""} value="integer">число</option>
	<option value="date">дата</option>
	<option value="photos">фотки (has_many)</option>
	<option value="photo">фотка (has_one)</option>
</select>


